package lastRites.game;

import java.io.IOException;

import lastRites.entities.Player;
import lastRites.enums.CreatureType;
import lastRites.enums.GameStatus;
import lastRites.game.networking.Network;
import lastRites.game.terrain.World;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class LastRitesNetworkDemo extends BasicGameState {
	private final int	VELOCITY_CAP	= 10;
	private String		IP				= "";
	private String		keyedIn			= "";
	private boolean		movingUp, movingDown, movingLeft, movingRight;

	@Override
	public void init(GameContainer container, StateBasedGame game) throws SlickException {
		// pick state, server or client
		LastRites.FRICTION.x = 1f;
		LastRites.FRICTION.y = 1f;
		LastRites.GRAVITY.x = 0;
		LastRites.GRAVITY.y = 150f;
		LastRites.CURRENT_WORLD = new World();
		LastRites.THIS_PLAYER.setCreatureType( CreatureType.GOLEM );
		LastRites.THIS_PLAYER.setCurrentWorld( LastRites.CURRENT_WORLD );
	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
		switch( LastRites.GAME_STATUS ) {
			case ENTERINGIP:
				g.drawString( "Enter an IP address", 15, 25 );
				g.drawString( keyedIn, 30, 402 );
				g.drawRect( 25, 400, 590, 20 );
				break;
			case INITIALNETWORK:
				g.drawString( "1. Host a server", 25, 50 );
				g.drawString( "2. Connect to a server", 25, 65 );
				g.drawString( "3. Play by yourself :(", 25, 80 );
				break;
			case CONNECTING:
				g.drawString( "Trying to connect to...", 75, 125 );
				g.scale( 2, 2 );
				g.translate( 55, 70 );
				if( Math.random() < 0.90 ) {
					g.drawString( IP, 0 + (float)Math.random(), 0 + (float)Math.random() );
				}
				g.resetTransform();
				break;
			case LISTENING:
				if( Math.random() < 0.2 ) {
					float transX = 0, transY = 0;
					if( Math.random() < 0.5 ) {
						transX = -20 + (float)Math.random() * 40;
						transY = -15 + (float)Math.random() * 30;
					}
					g.translate( transX, transY );
					g.drawString( "Waiting for others to join...", 100, 50 );
					g.translate( -transX, -transY );
				} else {
					g.drawString( "Waiting for others to join...", 100, 50 );
				}
				break;
			case LOGGINGON:
				g.scale( 2, 2 );
				g.drawString( "Logged in!", 75, 125 );
				g.scale( .5f, .5f );
				break;
			case SERVING:
				g.scale( 2, 2 );
				g.drawString( "Found players!", 75, 125 );
				g.scale( .5f, .5f );
				break;
			case HOSTINGGAME:
			case INGAME:
				// Translate to adjust for camera, everything should be inside this
				g.translate( LastRites.SCREEN_WIDTH / 2 - LastRites.THIS_PLAYER.getCenter().x, LastRites.SCREEN_HEIGHT / 2 - LastRites.THIS_PLAYER.getCenter().y );
				// START Parallax attempt :<
				float skyXOffset = ( -0.1f * LastRites.THIS_PLAYER.getCenter().x ) % LastRites.MISC_IMAGES.get( "sky" ).getWidth();
				float skyYOffset = -0.05f * LastRites.THIS_PLAYER.getCenter().y;
				float backgroundStartX = LastRites.THIS_PLAYER.getCenter().x - LastRites.SCREEN_WIDTH / 2;
				float backgroundStartY = LastRites.THIS_PLAYER.getCenter().y - LastRites.SCREEN_HEIGHT / 2;
				LastRites.THIS_PLAYER.setMovementSpeed( 450f );
				g.translate( skyXOffset, skyYOffset );
				int skyCopiesToUse = 2 + (int)( LastRites.SCREEN_WIDTH / LastRites.MISC_IMAGES.get( "sky" ).getWidth() );
				for( int skyIndex = 0; skyIndex < skyCopiesToUse; skyIndex++ ) {
					g.drawImage( LastRites.MISC_IMAGES.get( "sky" ), backgroundStartX + ( skyIndex * LastRites.MISC_IMAGES.get( "sky" ).getWidth() ), backgroundStartY );
				}
				g.translate( -skyXOffset, -skyYOffset );
				float mountainsXOffset = ( -0.12f * LastRites.THIS_PLAYER.getCenter().x ) % LastRites.MISC_IMAGES.get( "mountain_range" ).getWidth();
				float mountainsYOffset = -0.05f * LastRites.THIS_PLAYER.getCenter().y;
				g.translate( mountainsXOffset, mountainsYOffset );
				int mountainCopiesToUse = 2 + (int)( LastRites.SCREEN_WIDTH / LastRites.MISC_IMAGES.get( "mountain_range" ).getWidth() );
				for( int mountainIndex = 0; mountainIndex < mountainCopiesToUse; mountainIndex++ ) {
					g.drawImage( LastRites.MISC_IMAGES.get( "mountain_range" ), backgroundStartX + ( mountainIndex * LastRites.MISC_IMAGES.get( "mountain_range" ).getWidth() ), backgroundStartY );
				}
				g.translate( -mountainsXOffset, -mountainsYOffset );
				// END Parallax
				// Draw blocks
				int centerScreenRow = (int)( LastRites.THIS_PLAYER.getCenter().y / LastRites.BLOCK_SIZE );
				int centerScreenCol = (int)( LastRites.THIS_PLAYER.getCenter().x / LastRites.BLOCK_SIZE );
				for( int row = 0; row < LastRites.CURRENT_WORLD.getBlocks().length; row++ ) {
					for( int col = 0; col < LastRites.CURRENT_WORLD.getBlocks()[0].length; col++ ) {
						if( Math.abs( row - centerScreenRow ) < ( LastRites.SCREEN_HEIGHT / LastRites.BLOCK_SIZE ) / 2 + 1 && Math.abs( col - centerScreenCol ) < ( LastRites.SCREEN_WIDTH / LastRites.BLOCK_SIZE ) / 2 + 1 ) {
							LastRites.CURRENT_WORLD.getBlocks()[row][col].render( container, game, g );
						}
					}
				}
				g.drawRect( 0, 16 * 30, 16, 16 );
				// Draw players
				for( Player p : LastRites.PLAYER_LIST ) {
					p.render( container, game, g );
				}
				g.translate( -LastRites.SCREEN_WIDTH / 2 + LastRites.THIS_PLAYER.getCenter().x, -LastRites.SCREEN_HEIGHT / 2 + LastRites.THIS_PLAYER.getCenter().y );
				break;
		}
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
		switch( LastRites.GAME_STATUS ) {
			case SERVING:
				break;
			case HOSTINGGAME:
			case INGAME:
				LastRites.THIS_PLAYER.update( container, game, delta );
				// if( movingUp ) {
				// LastRites.THIS_PLAYER.getVelocity().y = Math.max( LastRites.THIS_PLAYER.getVelocity().y -
				// LastRites.THIS_PLAYER.getMovementSpeed() * ( (float)delta / 500 ),
				// -VELOCITY_CAP );
				// }
				// if( movingDown ) {
				// LastRites.THIS_PLAYER.getVelocity().y = Math.min( LastRites.THIS_PLAYER.getVelocity().y +
				// LastRites.THIS_PLAYER.getMovementSpeed() * ( (float)delta / 500 ),
				// VELOCITY_CAP );
				// }
				// if( movingLeft ) {
				// LastRites.THIS_PLAYER.getVelocity().x = Math.max( LastRites.THIS_PLAYER.getVelocity().x -
				// LastRites.THIS_PLAYER.getMovementSpeed() * ( (float)delta / 500 ),
				// -VELOCITY_CAP );
				// }
				// if( movingRight ) {
				// LastRites.THIS_PLAYER.getVelocity().x = Math.min( LastRites.THIS_PLAYER.getVelocity().x +
				// LastRites.THIS_PLAYER.getMovementSpeed() * ( (float)delta / 500 ),
				// VELOCITY_CAP );
				// }
				// LastRites.THIS_PLAYER.getPosition().add( LastRites.THIS_PLAYER.getVelocity() );
				break;
		}
	}

	@Override
	public void keyPressed(int key, char c) {
		System.out.println( key );
		switch( LastRites.GAME_STATUS ) {
			case INITIALNETWORK:
				switch( c ) {
					case '1':
						// set to server
						LastRites.PLAYER_LIST.add( LastRites.THIS_PLAYER );
						try {
							LastRites.SERVER = Network.setupServer();
							LastRites.GAME_STATUS = GameStatus.LISTENING;
						} catch( IOException e ) {
							e.printStackTrace();
						}
						break;
					case '2':
						// set to client
						LastRites.CLIENT = Network.setupClient();
						LastRites.GAME_STATUS = GameStatus.ENTERINGIP;
						break;
					case '3':
						LastRites.PLAYER_LIST.add( LastRites.THIS_PLAYER );
						try {
							LastRites.SERVER = Network.setupSinglePlayerServer();
							LastRites.CLIENT = Network.setupClient();
							LastRites.CLIENT.connect( 5000, IP, 6112 );
						} catch( IOException e ) {
							e.printStackTrace();
						}
						break;
				}
				break;
			case ENTERINGIP:
				if( key == 14 ) {
					keyedIn = keyedIn.substring( 0, Math.max( 0, keyedIn.length() - 1 ) );
				} else if( key == 28 ) {
					IP = keyedIn;
					keyedIn = "";
					tryConnection();
				} else {
					keyedIn += c;
				}
				break;
			case HOSTINGGAME:
			case INGAME:
				if( c == 'w' ) {
					movingUp = true;
				}
				if( c == 'a' ) {
					movingLeft = true;
				}
				if( c == 's' ) {
					movingDown = true;
				}
				if( c == 'd' ) {
					movingRight = true;
				}
				break;
			case CONNECTING:
		}
	}

	@Override
	public void keyReleased(int key, char c) {
		switch( LastRites.GAME_STATUS ) {
			case HOSTINGGAME:
			case INGAME:
				if( c == 'w' ) {
					movingUp = false;
				}
				if( c == 'a' ) {
					movingLeft = false;
				}
				if( c == 's' ) {
					movingDown = false;
				}
				if( c == 'd' ) {
					movingRight = false;
				}
				break;
		}
	}

	public void tryConnection() {
		try {
			LastRites.CLIENT.start();
			LastRites.CLIENT.connect( 5000, IP, 6112 );
			LastRites.GAME_STATUS = GameStatus.CONNECTING;
		} catch( IOException e ) {
			e.printStackTrace();
		}
	}

	@Override
	public int getID() {
		return 2;
	}

}
